home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / net / ds3100.md / netLE.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  15KB  |  609 lines

  1. /* 
  2.  * netLE.c --
  3.  *
  4.  *    The main routines for the device driver for the AMD 7990 Ethernet 
  5.  *    Controller.
  6.  *
  7.  * Copyright (C) 1989 Digital Equipment Corporation.
  8.  * Permission to use, copy, modify, and distribute this software and
  9.  * its documentation for any purpose and without fee is hereby granted,
  10.  * provided that the above copyright notice appears in all copies.  
  11.  * Digital Equipment Corporation makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as is"
  13.  * without express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/net/ds3100.md/netLE.c,v 9.6 92/04/14 16:57:27 jhh Exp $ SPRITE (DECWRL)";
  18. #endif not lint
  19.  
  20. #include <netInt.h>
  21. #include <sprite.h>
  22. #include <sys.h>
  23. #include <list.h>
  24. #include <vm.h>
  25. #include <vmMach.h>
  26. #include <mach.h>
  27. #include <netLEInt.h>
  28. #include <machAddrs.h>
  29. #include <assert.h>
  30.  
  31. Address    NetLEMemAlloc();
  32.  
  33. NetLEState    netLEDebugState;
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * NetLEInit --
  40.  *
  41.  *    Initialize the LANCE AMD 7990 Ethernet chip.
  42.  *
  43.  * Results:
  44.  *    SUCCESS if the LANCE controller was found and initialized,
  45.  *    FAILURE otherwise.
  46.  *
  47.  * Side effects:
  48.  *    Initializes the netEtherFuncs record, as well as the chip.
  49.  *
  50.  *----------------------------------------------------------------------
  51.  */
  52. ReturnStatus
  53. NetLEInit(interPtr)
  54.     Net_Interface    *interPtr;     /* Network interface. */
  55. {
  56.     Address         ctrlAddr;/* Kernel virtual address of controller. */
  57.     int         i;
  58.     List_Links        *itemPtr;
  59.     NetLEState        *statePtr;
  60.     char        buffer[32];
  61.     ReturnStatus    status;
  62.  
  63.     assert(sizeof(NetLE_Reg) == 4);
  64.  
  65.     DISABLE_INTR();
  66.  
  67.     ctrlAddr = interPtr->ctrlAddr;
  68.     /*
  69.      * If the address is physical (not in kernel's virtual address space)
  70.      * then we have to map it in.
  71.      */
  72.     if (interPtr->virtual == FALSE) {
  73.     printf("NetLEInit: ds3100 does not support mapping in devices yet.\n");
  74.     printf("NetLEInit: can't map in network device at 0x%x\n", ctrlAddr);
  75.     return FAILURE;
  76. #if 0
  77.     ctrlAddr = (char *) VmMach_MapInDevice(ctrlAddr, 1);
  78. #endif
  79.     }
  80.     statePtr = (NetLEState *) malloc (sizeof(NetLEState));
  81.     statePtr->running = FALSE;
  82.  
  83.     /*
  84.      * The onboard control register is at a pre-defined kernel virtual
  85.      * address.
  86.      */
  87.     statePtr->regDataPortPtr = (unsigned short *)MACH_NETWORK_INTERFACE_ADDR;
  88.     statePtr->regAddrPortPtr = statePtr->regDataPortPtr + 2;
  89.     {
  90.     /*
  91.      * Poke the controller by setting the RAP.
  92.      */
  93.     short value = NET_LE_CSR0_ADDR;
  94.     ReturnStatus status;
  95.     status = Mach_Probe(sizeof(short), (char *) &value, 
  96.               (char *) statePtr->regAddrPortPtr);
  97.     if (status != SUCCESS) {
  98.         /*
  99.          * Got a bus error.
  100.          */
  101.         free((char *) statePtr);
  102.         ENABLE_INTR();
  103.         return(FAILURE);
  104.     }
  105.     }
  106.     Mach_SetHandler(interPtr->vector, Net_Intr, (ClientData) interPtr);
  107.     /*
  108.      * Initialize the transmission list.  
  109.      */
  110.     statePtr->xmitList = &statePtr->xmitListHdr;
  111.     List_Init(statePtr->xmitList);
  112.  
  113.     statePtr->xmitFreeList = &statePtr->xmitFreeListHdr;
  114.     List_Init(statePtr->xmitFreeList);
  115.  
  116.     for (i = 0; i < NET_LE_NUM_XMIT_ELEMENTS; i++) {
  117.     itemPtr = (List_Links *) malloc(sizeof(NetXmitElement)), 
  118.     List_InitElement(itemPtr);
  119.     List_Insert(itemPtr, LIST_ATREAR(statePtr->xmitFreeList));
  120.     }
  121.  
  122.     Mach_GetEtherAddress(&statePtr->etherAddress);
  123.     (void) Net_EtherAddrToString(&statePtr->etherAddress, buffer);
  124.     printf("%s-%d Ethernet address %s\n", interPtr->name, interPtr->number, 
  125.         buffer);
  126.     /*
  127.      * Allocate the initialization block.
  128.      */
  129.     statePtr->initBlockPtr = NetLEMemAlloc(NET_LE_INIT_SIZE, TRUE);
  130.  
  131.     interPtr->init    = NetLEInit;
  132.     interPtr->output     = NetLEOutput;
  133.     interPtr->intr    = NetLEIntr;
  134.     interPtr->ioctl    = NetLEIOControl;
  135.     interPtr->reset     = NetLERestart;
  136.     interPtr->getStats    = NetLEGetStats;
  137.     interPtr->netType    = NET_NETWORK_ETHER;
  138.     interPtr->maxBytes    = NET_ETHER_MAX_BYTES - sizeof(Net_EtherHdr);
  139.     interPtr->minBytes    = 0;
  140.     interPtr->interfaceData = (ClientData) statePtr;
  141.     status = Net_SetAddress(NET_ADDRESS_ETHER, 
  142.         (Address) &statePtr->etherAddress,
  143.         &interPtr->netAddress[NET_PROTO_RAW]);
  144.     if (status != SUCCESS) {
  145.     panic("NetLEInit: Net_SetAddress failed\n");
  146.     }
  147.     interPtr->broadcastAddress = netEtherBroadcastAddress;
  148.     interPtr->flags |= NET_IFLAGS_BROADCAST;
  149.     statePtr->interPtr = interPtr;
  150.     statePtr->recvMemInitialized = FALSE;
  151.     statePtr->recvMemAllocated = FALSE;
  152.     statePtr->xmitMemInitialized = FALSE;
  153.     statePtr->xmitMemAllocated = FALSE;
  154.  
  155.  
  156.     /*
  157.      * Reset the world.
  158.      */
  159.     NetLEReset(interPtr);
  160.  
  161.     /*
  162.      * Now we are running.
  163.      */
  164.  
  165.     statePtr->running = TRUE;
  166.     ENABLE_INTR();
  167.     return (SUCCESS);
  168. }
  169.  
  170.  
  171. /*
  172.  *----------------------------------------------------------------------
  173.  *
  174.  * NetLEReset --
  175.  *
  176.  *    Reset the world.
  177.  *
  178.  * Results:
  179.  *    None.
  180.  *
  181.  * Side effects:
  182.  *    All of the pointers in the netLEState structure are initialized.
  183.  *
  184.  *----------------------------------------------------------------------
  185.  */
  186. void
  187. NetLEReset(interPtr)
  188.     Net_Interface    *interPtr; /* Interface to reset. */
  189. {
  190.     NetLEState        *statePtr;
  191.     unsigned        addr;
  192.     int            i;
  193.  
  194.     statePtr = (NetLEState *) interPtr->interfaceData;
  195.     /* 
  196.      * Reset (and stop) the chip.
  197.      */
  198.     *statePtr->regAddrPortPtr = NET_LE_CSR0_ADDR;
  199.     *statePtr->regDataPortPtr = NET_LE_CSR0_STOP; 
  200.  
  201.     /*
  202.      * Set up the receive and transmit rings. 
  203.      */
  204.      NetLERecvInit(statePtr);
  205.      NetLEXmitInit(statePtr);
  206.  
  207.     /*
  208.      * Zero out the mode word.
  209.      */
  210.     *BUF_TO_ADDR(statePtr->initBlockPtr,NET_LE_INIT_MODE)=0;
  211.     /*
  212.      * Insert the ethernet address.
  213.      */
  214.     *BUF_TO_ADDR(statePtr->initBlockPtr, 
  215.               NET_LE_INIT_ETHER_ADDR) = 
  216.             (unsigned char)statePtr->etherAddress.byte1 |
  217.             ((unsigned char)statePtr->etherAddress.byte2 << 8);
  218.     *BUF_TO_ADDR(statePtr->initBlockPtr, 
  219.               NET_LE_INIT_ETHER_ADDR + 2) = 
  220.             (unsigned char)statePtr->etherAddress.byte3 | 
  221.             ((unsigned char)statePtr->etherAddress.byte4 << 8);
  222.     *BUF_TO_ADDR(statePtr->initBlockPtr, 
  223.             NET_LE_INIT_ETHER_ADDR + 4) = 
  224.             (unsigned char)statePtr->etherAddress.byte5 | 
  225.             ((unsigned char)statePtr->etherAddress.byte6 << 8);
  226.     /*
  227.      * Reject all multicast addresses.
  228.      */
  229.     for (i = 0; i < 4; i++) {
  230.     *BUF_TO_ADDR(statePtr->initBlockPtr, 
  231.               NET_LE_INIT_MULTI_MASK + (sizeof(short) * i)) = 0;
  232.     }
  233.     /*
  234.      * We want to get boot multicasts.
  235.      * These are addr ab-00-00-01-00-00 = hash bit 31?
  236.      */
  237.     *BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_MULTI_MASK) = 0x8000;
  238.  
  239.     /*
  240.      * Set up the receive ring pointer.
  241.      */
  242.     addr = BUF_TO_CHIP_ADDR(statePtr->recvDescFirstPtr);
  243.     *BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_RECV_LOW) = addr & 0xffff;
  244.     *BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_RECV_HIGH) =
  245.                 (unsigned)((addr >> 16) & 0xff) |
  246.         ((unsigned)((NET_LE_NUM_RECV_BUFFERS_LOG2 << 5) & 0xe0) << 8);
  247.     if (*BUF_TO_ADDR(statePtr->initBlockPtr,
  248.                   NET_LE_INIT_RECV_LOW) & 0x07) {
  249.     printf("netLE: Receive list not on QUADword boundary\n");
  250.     return;
  251.     }
  252.  
  253.     /*
  254.      * Set up the transmit ring pointer.
  255.      */
  256.     addr = BUF_TO_CHIP_ADDR(statePtr->xmitDescFirstPtr);
  257.     *BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_XMIT_LOW) = addr & 0xffff;
  258.     *BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_XMIT_HIGH) =
  259.                 (unsigned)((addr >> 16) & 0xff) |
  260.         ((unsigned)((NET_LE_NUM_XMIT_BUFFERS_LOG2 << 5) & 0xe0) << 8);
  261.     if (*BUF_TO_ADDR(statePtr->initBlockPtr, NET_LE_INIT_XMIT_LOW) & 0x07) {
  262.     printf("netLE: Transmit list not on QUADword boundary\n");
  263.     return;
  264.     }
  265.  
  266.     /*
  267.      * Clear the Bus master control register (csr3).
  268.      */
  269.     *statePtr->regAddrPortPtr = NET_LE_CSR3_ADDR;
  270.     *statePtr->regDataPortPtr = 0;
  271.  
  272.     /*
  273.      * Set the init block pointer address in csr1 and csr2
  274.      */
  275.     addr = BUF_TO_CHIP_ADDR(statePtr->initBlockPtr);
  276.     *statePtr->regAddrPortPtr = NET_LE_CSR1_ADDR;
  277.     *statePtr->regDataPortPtr = (short)(addr & 0xffff);
  278.  
  279.     *statePtr->regAddrPortPtr = NET_LE_CSR2_ADDR;
  280.     *statePtr->regDataPortPtr = (short)((addr >> 16) & 0xff);
  281.  
  282.     /*
  283.      * Tell the chip to initialize and wait for results.
  284.      */
  285.     *statePtr->regAddrPortPtr = NET_LE_CSR0_ADDR;
  286.     *statePtr->regDataPortPtr = NET_LE_CSR0_INIT | NET_LE_CSR0_INIT_DONE;
  287.  
  288.     {
  289.     int    i;
  290.     volatile unsigned short *csr0Ptr = statePtr->regDataPortPtr;
  291.  
  292.  
  293.     for (i = 0; ((*csr0Ptr & NET_LE_CSR0_INIT_DONE) == 0); i++) {
  294.         if (i > 50000) {
  295.         panic( "LE ethernet: Chip will not initialize.\n");
  296.         }
  297.     }
  298.  
  299.     /*
  300.      * Ack the interrupt.
  301.      */
  302.      *csr0Ptr = NET_LE_CSR0_INIT_DONE;
  303.     }
  304.  
  305.     /*
  306.      * Start the chip and enable interrupts.
  307.      */
  308.     *statePtr->regDataPortPtr = 
  309.             (NET_LE_CSR0_START | NET_LE_CSR0_INTR_ENABLE);
  310.  
  311.     printf("LE ethernet: Reinitialized chip.\n");
  312.     interPtr->flags |= NET_IFLAGS_RUNNING;
  313.  
  314. }
  315.  
  316.  
  317. /*
  318.  *----------------------------------------------------------------------
  319.  *
  320.  * NetLERestart --
  321.  *
  322.  *    Reinitialize the LANCE Ethernet chip.
  323.  *
  324.  * Results:
  325.  *    None.
  326.  *
  327.  * Side effects:
  328.  *    None.
  329.  *
  330.  *----------------------------------------------------------------------
  331.  */
  332. void
  333. NetLERestart(interPtr)
  334.     Net_Interface    *interPtr;     /* Interface to restart. */
  335. {
  336.     NetLEState    *statePtr = (NetLEState *) interPtr->interfaceData;
  337.  
  338.     DISABLE_INTR();
  339.  
  340.     /*
  341.      * Drop the current packet so the sender does't get hung.
  342.      */
  343.     NetLEXmitDrop(statePtr);
  344.  
  345.     /*
  346.      * Reset the world.
  347.      */
  348.     NetLEReset(interPtr);
  349.  
  350.     /*
  351.      * Restart transmission of packets.
  352.      */
  353.     NetLEXmitRestart(statePtr);
  354.  
  355.     ENABLE_INTR();
  356. }
  357.  
  358.  
  359. /*
  360.  *----------------------------------------------------------------------
  361.  *
  362.  * NetLEIntr --
  363.  *
  364.  *    Process an interrupt from the LANCE chip.
  365.  *
  366.  * Results:
  367.  *    None.
  368.  *
  369.  * Side effects:
  370.  *    None.
  371.  *
  372.  *----------------------------------------------------------------------
  373.  */
  374. void
  375. NetLEIntr(interPtr, polling)
  376.     Net_Interface    *interPtr;    /* Network interface.*/
  377.     Boolean    polling;        /* TRUE if are being polled instead of
  378.                      * processing an interrupt. */
  379. {
  380.     volatile register    NetLEState    *statePtr;
  381.     ReturnStatus        statusXmit, statusRecv;
  382.     register unsigned short    csr0;
  383.     Boolean            reset;
  384.  
  385.     statePtr = (NetLEState *) interPtr->interfaceData;
  386.     *statePtr->regAddrPortPtr = NET_LE_CSR0_ADDR;
  387.     csr0 = *statePtr->regDataPortPtr;
  388.  
  389.     /*
  390.      * Check for errors.
  391.      */
  392.  
  393.     if (csr0 & NET_LE_CSR0_ERROR) {
  394.     reset = TRUE;
  395.     if (csr0 & NET_LE_CSR0_MISSED_PACKET) {
  396.         printf("LE ethernet: Missed a packet.\n");
  397.         /*
  398.          * Clear interrupt bit but don't reset controller.
  399.          */
  400.         *statePtr->regDataPortPtr = NET_LE_CSR0_MISSED_PACKET;
  401.         reset = FALSE;
  402.     }
  403.     if (csr0 & NET_LE_CSR0_COLLISION_ERROR) {
  404.         /*
  405.          * Late collision error appear to happen when the machine
  406.          * is disconnected from the transceiver. When this happens
  407.          * we will complain about Lost of Carrier so the late
  408.          * collision message is uncessary.
  409.          *
  410.          * printf("LE ethernet: Late collision.\n");
  411.          */
  412.         reset = FALSE;
  413.     }
  414.     /*
  415.      * Check for fatal errors.  Kill the machine if we start babbling 
  416.      * (sending oversize ethernet packets). 
  417.      */
  418.     if (csr0 & NET_LE_CSR0_BABBLE) {
  419.         panic("LE ethernet: Transmit babble.\n");
  420.     }
  421.     if (csr0 & NET_LE_CSR0_MEMORY_ERROR) {
  422.         panic("LE ethernet: Memory Error.\n");
  423.     }
  424.     /*
  425.      * Clear the error the easy way, reinitialize everything.
  426.      */
  427.     if (reset == TRUE) {
  428.         NetLERestart(interPtr);
  429.         return;
  430.     }
  431.     }
  432.  
  433.     statusRecv = statusXmit = SUCCESS;
  434.     /*
  435.      * Did we receive a packet.
  436.      */
  437.     if (csr0 & NET_LE_CSR0_RECV_INTR) {
  438.     statusRecv = NetLERecvProcess(FALSE, statePtr);
  439.     }
  440.     /*
  441.      * Did we transmit a packet.
  442.      */
  443.     if (csr0 & NET_LE_CSR0_XMIT_INTR) {
  444.     statusXmit = NetLEXmitDone(statePtr);
  445.     }
  446.     /*
  447.      * Did the chip magically initialize itself?
  448.      */
  449.     if (csr0 & NET_LE_CSR0_INIT_DONE) {
  450.     printf( "LE ethernet: Chip initialized itself!!\n");
  451.     /*
  452.      * Better initialize it the way we want it.
  453.      */
  454.     statusRecv = FAILURE;
  455.     }
  456.  
  457.     if (statusRecv != SUCCESS || statusXmit != SUCCESS) {
  458.     NetLERestart(interPtr);
  459.     return;
  460.     }
  461.     /*
  462.      * If interrupts aren't enabled or there is no interrupt pending, then
  463.      * what are we doing here?
  464.      */
  465.  
  466.     if ( !(csr0 & NET_LE_CSR0_INTR_ENABLE) || !(csr0 & NET_LE_CSR0_INTR) ) {
  467.     /*
  468.      * We could be polling; that's why we were here.
  469.      */
  470.     if (!polling) {
  471.         printf("LE ethernet: Spurious interrupt CSR0 = <%x>\n", csr0);
  472.     } 
  473.     } 
  474.     return;
  475.  
  476. }
  477.  
  478. unsigned    bufAddr = MACH_NETWORK_BUFFER_ADDR;
  479.  
  480. /*
  481.  *----------------------------------------------------------------------
  482.  *
  483.  * NetLEMemAlloc -- 
  484.  *
  485.  *    Allocate memory from the buffer.
  486.  *
  487.  * Results:
  488.  *    None.
  489.  *
  490.  * Side effects:
  491.  *    None.
  492.  *
  493.  *----------------------------------------------------------------------
  494.  */
  495. Address
  496. NetLEMemAlloc(numBytes, wordAlign)
  497.     unsigned int    numBytes;
  498.     Boolean        wordAlign;
  499. {
  500.     Address    retVal;
  501.  
  502.     if (wordAlign) {
  503.     bufAddr &= ~0x3;
  504.     } else {
  505.     bufAddr &= ~0xf;
  506.     }
  507.     retVal = (Address)bufAddr;
  508.     bufAddr += numBytes * 2;
  509.  
  510.     return(retVal);
  511. }
  512.  
  513. #ifdef notdef
  514.  
  515. /*
  516.  *----------------------------------------------------------------------
  517.  *
  518.  * BUF_TO_CHIP_ADDR -- 
  519.  *
  520.  *    Convert a memory buffer address to an address for the chip.  
  521.  *
  522.  *    NOTE: This used to a macro but was changed to C for debugging
  523.  *          purposes, hence the weird name.  Should probably change back
  524.  *          to a macro.
  525.  *
  526.  * Results:
  527.  *    None.
  528.  *
  529.  * Side effects:
  530.  *    None.
  531.  *
  532.  *----------------------------------------------------------------------
  533.  */
  534. unsigned
  535. BUF_TO_CHIP_ADDR(addr)
  536.     Address    addr;
  537. {
  538.     int    off, base, tmp;
  539.     int    retAddr;
  540.  
  541.     off = (int)addr & NET_LE_DMA_CHIP_ADDR_MASK;
  542.     base = (int)NET_LE_DMA_BUFFER_ADDR;
  543.     tmp = off / 2;
  544.     if (off == tmp * 2) {
  545.     retAddr = base + tmp;
  546.     } else {
  547.     printf("BUF_TO_CHIP_ADDR: odd offset\n");
  548.     retAddr = base + tmp + 1;
  549.     }
  550.     return(retAddr);
  551. }
  552. #endif
  553.  
  554. /*
  555.  *----------------------------------------------------------------------
  556.  *
  557.  * NetLEGetStats --
  558.  *
  559.  *    Return the statistics for the interface.
  560.  *
  561.  * Results:
  562.  *    A pointer to the statistics structure.
  563.  *
  564.  * Side effects:
  565.  *    None.
  566.  *
  567.  *----------------------------------------------------------------------
  568.  */
  569.  
  570. ReturnStatus
  571. NetLEGetStats(interPtr, statPtr)
  572.     Net_Interface    *interPtr;        /* Current interface. */
  573.     Net_Stats        *statPtr;        /* Statistics to return. */
  574. {
  575.     NetLEState    *statePtr;
  576.     statePtr = (NetLEState *) interPtr->interfaceData;
  577.     DISABLE_INTR();
  578.     statPtr->ether = statePtr->stats;
  579.     ENABLE_INTR();
  580.     return SUCCESS;
  581. }
  582.  
  583. /*
  584.  *----------------------------------------------------------------------
  585.  *
  586.  * NetLEIOControl --
  587.  *
  588.  *    Perform ioctls for the adapter.  Right now we don't support any.
  589.  *
  590.  * Results:
  591.  *    DEV_INVALID_ARG
  592.  *
  593.  * Side effects:
  594.  *    None.
  595.  *
  596.  *----------------------------------------------------------------------
  597.  */
  598.  
  599. /*ARGSUSED*/
  600. ReturnStatus
  601. NetLEIOControl(interPtr, ioctlPtr, replyPtr)
  602.     Net_Interface *interPtr;    /* Interface on which to perform ioctl. */
  603.     Fs_IOCParam *ioctlPtr;    /* Standard I/O Control parameter block */
  604.     Fs_IOReply *replyPtr;    /* Size of outBuffer and returned signal */
  605. {
  606.     return DEV_INVALID_ARG;
  607. }
  608.  
  609.